home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / OpenGL 1.0 SDK / Source / Examples / aux / samples / select.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-18  |  7.4 KB  |  415 lines  |  [TEXT/CWIE]

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include "tk.h"
  7.  
  8.  
  9. #define MAXOBJS 10000
  10. #define MAXSELECT 100
  11. #define MAXFEED 300
  12. #define    SOLID 1
  13. #define    LINE 2
  14. #define    POINT 3
  15.  
  16.  
  17. GLenum directRender;
  18. GLint windW, windH;
  19.  
  20. GLuint selectBuf[MAXSELECT];
  21. GLfloat feedBuf[MAXFEED];
  22. GLint vp[4];
  23. float zRotation = 90.0;
  24. float zoom = 1.0;
  25. GLint objectCount;
  26. GLint numObjects;
  27. struct object {
  28.     float v1[2];
  29.     float v2[2];
  30.     float v3[2];
  31.     float color[3];
  32. } objects[MAXOBJS];
  33. GLenum linePoly = GL_FALSE;
  34.  
  35.  
  36. static void InitObjects(GLint num)
  37. {
  38.     GLint i;
  39.     float x, y;
  40.  
  41.     if (num > MAXOBJS) {
  42.     num = MAXOBJS;
  43.     }
  44.     if (num < 1) {
  45.     num = 1;
  46.     }
  47.     objectCount = num;
  48.  
  49.     srand((unsigned int)time(NULL));
  50.     for (i = 0; i < num; i++) {
  51.     x = (rand() % 300) - 150;
  52.     y = (rand() % 300) - 150;
  53.  
  54.     objects[i].v1[0] = x + (rand() % 50) - 25;
  55.     objects[i].v2[0] = x + (rand() % 50) - 25;
  56.     objects[i].v3[0] = x + (rand() % 50) - 25;
  57.     objects[i].v1[1] = y + (rand() % 50) - 25;
  58.     objects[i].v2[1] = y + (rand() % 50) - 25;
  59.     objects[i].v3[1] = y + (rand() % 50) - 25;
  60.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  61.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  62.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  63.     }
  64. }
  65.  
  66. static void Init(void)
  67. {
  68.  
  69.     numObjects = 10;
  70.     InitObjects(numObjects);
  71.     glGetIntegerv(GL_VIEWPORT, vp);
  72. }
  73.  
  74. static void Reshape(int width, int height)
  75. {
  76.  
  77.     windW = (GLint)width;
  78.     windH = (GLint)height;
  79. }
  80.  
  81. static void Render(GLenum mode)
  82. {
  83.     GLint i;
  84.  
  85.     for (i = 0; i < objectCount; i++) {
  86.     if (mode == GL_SELECT) {
  87.         glLoadName(i);
  88.     }
  89.     glColor3fv(objects[i].color);
  90.     glBegin(GL_POLYGON);
  91.         glVertex2fv(objects[i].v1);
  92.         glVertex2fv(objects[i].v2);
  93.         glVertex2fv(objects[i].v3);
  94.     glEnd();
  95.     }
  96.     
  97.     tkSwapBuffers();
  98. }
  99.  
  100. static GLint DoSelect(GLint x, GLint y)
  101. {
  102.     GLint hits;
  103.  
  104.     glSelectBuffer(MAXSELECT, selectBuf);
  105.     (void)glRenderMode(GL_SELECT);
  106.     glInitNames();
  107.     glPushName(~0);
  108.  
  109.     glPushMatrix();
  110.  
  111.     glViewport(0, 0, windW, windH);
  112.     glGetIntegerv(GL_VIEWPORT, vp);
  113.  
  114.     glMatrixMode(GL_PROJECTION);
  115.     glLoadIdentity();
  116.     gluPickMatrix(x, windH-y, 4, 4, vp);
  117.     gluOrtho2D(-175, 175, -175, 175);
  118.     glMatrixMode(GL_MODELVIEW);
  119.  
  120.     glClearColor(0.0, 0.0, 0.0, 0.0);
  121.     glClear(GL_COLOR_BUFFER_BIT);
  122.  
  123.     glScalef(zoom, zoom, zoom);
  124.     glRotatef(zRotation, 0, 0, 1);
  125.  
  126.     Render(GL_SELECT);
  127.  
  128.     glPopMatrix();
  129.     
  130.     hits = glRenderMode(GL_RENDER); 
  131.     if (hits <= 0) {
  132.     return -1;
  133.     }
  134.  
  135.     return selectBuf[(hits-1)*4+3];
  136. }
  137.  
  138. static void RecolorTri(GLint h)
  139. {
  140.  
  141.     objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  142.     objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  143.     objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  144. }
  145.  
  146. static void DeleteTri(GLint h)
  147. {
  148.  
  149.     objects[h] = objects[objectCount-1];
  150.     objectCount--;
  151. }
  152.  
  153. static void GrowTri(GLint h)
  154. {
  155.     float v[2];
  156.     float *oldV;
  157.     GLint i;
  158.  
  159.     v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  160.     v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  161.     v[0] /= 3;
  162.     v[1] /= 3;
  163.  
  164.     for (i = 0; i < 3; i++) {
  165.     switch (i) {
  166.       case 0:
  167.         oldV = objects[h].v1;
  168.         break;
  169.       case 1:
  170.         oldV = objects[h].v2;
  171.         break;
  172.       case 2:
  173.         oldV = objects[h].v3;
  174.         break;
  175.     }
  176.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  177.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  178.     }
  179. }
  180.  
  181. static GLenum Mouse(int mouseX, int mouseY, GLenum button)
  182. {
  183.     GLint hit;
  184.  
  185.     hit = DoSelect((GLint)mouseX, (GLint)mouseY);
  186.     if (hit != -1) {
  187.     if (button & TK_LEFTBUTTON) {
  188.         RecolorTri(hit);
  189.     }
  190.     if (button & TK_MIDDLEBUTTON) {
  191.         GrowTri(hit);
  192.     }
  193.     if (button & TK_RIGHTBUTTON) {
  194.         DeleteTri(hit);
  195.     }
  196.     return GL_TRUE;
  197.     }
  198.     return GL_FALSE;
  199. }
  200.  
  201. static void Draw(void)
  202. {
  203.  
  204.     glPushMatrix();
  205.  
  206.     glViewport(0, 0, windW, windH);
  207.     glGetIntegerv(GL_VIEWPORT, vp);
  208.  
  209.     glMatrixMode(GL_PROJECTION);
  210.     glLoadIdentity();
  211.     gluOrtho2D(-175, 175, -175, 175);
  212.     glMatrixMode(GL_MODELVIEW);
  213.  
  214.     glClearColor(0.0, 0.0, 0.0, 0.0);
  215.     glClear(GL_COLOR_BUFFER_BIT);
  216.  
  217.     glScalef(zoom, zoom, zoom);
  218.     glRotatef(zRotation, 0, 0, 1);
  219.  
  220.     Render(GL_RENDER);
  221.  
  222.     glPopMatrix();
  223.  
  224.     glFlush();
  225. }
  226.  
  227. static void DumpFeedbackVert(GLint *i, GLint n)
  228. {
  229.     GLint index;
  230.  
  231.     index = *i;
  232.     if (index+7 > n) {
  233.     *i = n;
  234.     printf("  ???\n");
  235.     return;
  236.     }
  237.     printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  238.        feedBuf[index],
  239.        feedBuf[index+1],
  240.        feedBuf[index+2],
  241.        feedBuf[index+3],
  242.        feedBuf[index+4],
  243.        feedBuf[index+5]);
  244.     index += 7;
  245.     *i = index;
  246. }
  247.  
  248. static void DrawFeedback(GLint n)
  249. {
  250.     GLint i;
  251.     GLint verts;
  252.  
  253.     printf("Feedback results (%d floats):\n", n);
  254.     for (i = 0; i < n; i++) {
  255.     switch ((GLint)feedBuf[i]) {
  256.       case GL_POLYGON_TOKEN:
  257.         printf("Polygon");
  258.         i++;
  259.         if (i < n) {
  260.         verts = (GLint)feedBuf[i];
  261.         i++;
  262.         printf(": %d vertices", verts);
  263.         } else {
  264.         verts = 0;
  265.         }
  266.         printf("\n");
  267.         while (verts) {
  268.         DumpFeedbackVert(&i, n);
  269.         verts--;
  270.         }
  271.         i--;
  272.         break;
  273.       case GL_LINE_TOKEN:
  274.         printf("Line:\n");
  275.         i++;
  276.         DumpFeedbackVert(&i, n);
  277.         DumpFeedbackVert(&i, n);
  278.         i--;
  279.         break;
  280.       case GL_LINE_RESET_TOKEN:
  281.         printf("Line Reset:\n");
  282.         i++;
  283.         DumpFeedbackVert(&i, n);
  284.         DumpFeedbackVert(&i, n);
  285.         i--;
  286.         break;
  287.       default:
  288.         printf("%9.2f\n", feedBuf[i]);
  289.         break;
  290.     }
  291.     }
  292.     if (i == MAXFEED) {
  293.     printf("...\n");
  294.     }
  295.     printf("\n");
  296. }
  297.  
  298. static void DoFeedback(void) 
  299. {
  300.     GLint x;
  301.  
  302.     glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  303.     (void)glRenderMode(GL_FEEDBACK);
  304.  
  305.     glPushMatrix();
  306.  
  307.     glViewport(0, 0, windW, windH);
  308.     glGetIntegerv(GL_VIEWPORT, vp);
  309.  
  310.     glMatrixMode(GL_PROJECTION);
  311.     glLoadIdentity();
  312.     gluOrtho2D(-175, 175, -175, 175);
  313.     glMatrixMode(GL_MODELVIEW);
  314.  
  315.     glClearColor(0.0, 0.0, 0.0, 0.0);
  316.     glClear(GL_COLOR_BUFFER_BIT);
  317.  
  318.     glScalef(zoom, zoom, zoom);
  319.     glRotatef(zRotation, 0, 0, 1);
  320.  
  321.     Render(GL_FEEDBACK);
  322.  
  323.     glPopMatrix();
  324.     
  325.     x = glRenderMode(GL_RENDER); 
  326.     if (x == -1) {
  327.     x = MAXFEED;
  328.     }
  329.  
  330.     DrawFeedback((GLint)x);
  331. }
  332.  
  333. static GLenum Key(int key, GLenum mask)
  334. {
  335.     switch (key) {
  336.       case TK_ESCAPE:
  337.     tkQuit();
  338.       case TK_LEFT:
  339.     zRotation += 0.5;
  340.     break;
  341.       case TK_RIGHT:
  342.     zRotation -= 0.5;
  343.     break;
  344.       case TK_Z:
  345.     zoom /= 0.75;
  346.     break;
  347.       case TK_z:
  348.     zoom *= 0.75;
  349.     break;
  350.       case TK_f:
  351.     DoFeedback();
  352.     break;
  353.       case TK_l:
  354.     linePoly = !linePoly;
  355.     if (linePoly) {
  356.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  357.     } else {
  358.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  359.     }
  360.     break;
  361.       default:
  362.     return GL_FALSE;
  363.     }
  364.     return GL_TRUE;
  365. }
  366.  
  367. static GLenum Args(int argc, char **argv)
  368. {
  369.     GLint i;
  370.  
  371.     directRender = GL_TRUE;
  372.  
  373.     for (i = 1; i < argc; i++) {
  374.     if (strcmp(argv[i], "-dr") == 0) {
  375.         directRender = GL_TRUE;
  376.     } else if (strcmp(argv[i], "-ir") == 0) {
  377.         directRender = GL_FALSE;
  378.     } else {
  379.         printf("%s (Bad option).\n", argv[i]);
  380.         return GL_FALSE;
  381.     }
  382.     }
  383.     return GL_TRUE;
  384. }
  385.  
  386. void main(int argc, char **argv)
  387. {
  388.     GLenum type;
  389.  
  390.     if (Args(argc, argv) == GL_FALSE) {
  391.     tkQuit();
  392.     }
  393.  
  394.     windW = 300;
  395.     windH = 300;
  396.     tkInitPosition(30, 60, windW, windH);
  397.  
  398.     type = TK_RGB | TK_DOUBLE;
  399.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  400.     tkInitDisplayMode(type);
  401.  
  402.     if (tkInitWindow("Select Test") == GL_FALSE) {
  403.     tkQuit();
  404.     }
  405.  
  406.     Init();
  407.  
  408.     tkExposeFunc(Reshape);
  409.     tkReshapeFunc(Reshape);
  410.     tkKeyDownFunc(Key);
  411.     tkMouseDownFunc(Mouse);
  412.     tkDisplayFunc(Draw);
  413.     tkExec();
  414. }
  415.